from __future__ import absolute_import
from __future__ import print_function
import os
import sys
import optparse
import config
from sumolib import checkBinary  # noqa
import traci  # noqa
import redis
import uuid
import math
import traci.constants as tc
import datetime
import time
from numpy import *
import threading

# we need to import python modules from the $SUMO_HOME/tools directory
if 'SUMO_HOME' in os.environ:
    tools = os.path.join(os.environ['SUMO_HOME'], 'tools')
    sys.path.append(tools)
else:
    sys.exit("please declare environment variable 'SUMO_HOME'")

pool = redis.ConnectionPool(host='172.18.100.27', port=32010, db=13, password='123')
r = redis.StrictRedis(connection_pool=pool)


def get_rsu_01_pos_and_id(rsu_id_01):
    rsu_id = rsu_id_01
    rsu_lon = 121.442927
    rsu_lat = 37.472724

    arr = [rsu_id, rsu_lon, rsu_lat]

    return arr


def get_rsu_02_pos_and_id(rsu_id_02):
    rsu_id = rsu_id_02
    rsu_lon = 121.433883
    rsu_lat = 37.461350

    arr = [rsu_id, rsu_lon, rsu_lat]

    return arr


def get_rsu_03_pos_and_id(rsu_id_03):
    rsu_id = rsu_id_03
    rsu_lon = 121.450597
    rsu_lat = 37.458871

    arr = [rsu_id, rsu_lon, rsu_lat]

    return arr


# 获取两个经纬度之间的距离
def get_distance(lat1, lon1, lat2, lon2):
    rad_lat1 = lat1 * math.pi / 180.0
    rad_lat2 = lat2 * math.pi / 180.0
    a = rad_lat1 - rad_lat2
    b = lon1 * math.pi / 180.0 - lon2 * math.pi / 180.0
    s = 2 * math.asin(math.sqrt(math.pow(math.sin(a / 2), 2) +
                                math.cos(rad_lat1) * math.cos(rad_lat2) * math.pow(math.sin(b / 2), 2)))
    s = s * 6378.137  # EARTH_RADIUS
    s = round(s * 10000) / 10000
    return s * 1000


# 三个rsu位置
rsu_id_01 = '1f267932'
rsu_id_02 = 'jf456f13'
rsu_id_03 = '456her3f'


def get_veh_info(id):
    # 通过id获取x，y坐标
    x, y = traci.vehicle.getPosition(id)
    # x，y坐标转换成经纬度
    lon, lat = traci.simulation.convertGeo(x, y)
    # 获取角度
    angle = traci.vehicle.getAngle(id)
    # 获取速度
    speed = traci.vehicle.getSpeed(id)
    # 类型
    type = traci.vehicle.getTypeID(id)
    # 车辆长度
    vehLength = traci.vehicle.getLength(id)
    # 车辆宽度
    vehWidth = traci.vehicle.getWidth(id)
    # 车辆高度
    vehHeight = traci.vehicle.getHeight(id)
    # 车辆信号灯状态 (0:不开转向灯 1:右转灯 2:左转灯 3:刹车灯 8:直行等红灯 10:左转等红灯)
    signal = traci.vehicle.getSignals(id)
    # 车辆颜色
    color = traci.vehicle.getColor(id)
    # 加速度
    accel = traci.vehicle.getAcceleration(id)

    arr = [lon, lat, angle, speed, vehLength, vehWidth, vehHeight, accel]
    return arr


def get_person_info(id):
    # 速度
    speed = traci.person.getSpeed(id)
    # 世界坐标
    x, y = traci.person.getPosition(id)
    # x，y坐标转换成经纬度
    lon, lat = traci.simulation.convertGeo(x, y)
    # 角度
    angle = traci.person.getAngle(id)
    # 类型
    type_id = traci.person.getTypeID(id)
    # # 高度
    # height = traci.person.getHeight(type_id)
    # 长度
    length = traci.person.getLength(id)
    # 宽度
    width = traci.person.getWidth(id)
    # # 加速度
    # accel = traci.person.getAccel(type_id)
    height = '1.7'
    accel = '0.5'

    arr = [lon, lat, angle, speed, length, width, height, accel]
    return arr


def traffic_accident_event_from_rsu(rsu_id, rsu_lon, rsu_lat, event_lon, event_lat):
    rsu_id = rsu_id
    rsu_lon = rsu_lon
    rsu_lat = rsu_lat
    rte_id = random.randint(0, 255)
    event_type = '100'
    event_source = '0'
    event_lon = event_lon
    event_lat = event_lat
    msg = '{"rsu_id":"' + rsu_id + '", "rsu_lon": "' + str(rsu_lon) + '", "rsu_lat": "' + str(rsu_lat) + \
          '", "rte_id": "' + str(rte_id) + '", "event_type": "' + event_type + \
          '", "event_source": "' + event_source + '", "event_lon": "' + str(event_lon) + \
          '", "event_lat": "' + str(event_lat) + '", "timestamp": "' + str(
        int(round((time.time()) * 1000))) + '"}'
    res = r.setnx('traffic_accident_rsi', 'traffic_accident_rsi')
    if res == True:
        rsi_traffic_accident_quene(msg)
        r.expire('traffic_accident_rsi', 5)
        print(msg)


def traffic_accident_distance_judge(distance_rsu_01, distance_rsu_02, distance_rsu_03, rsu_id_01, rsu_id_02, rsu_id_03,
                                    event_lon, event_lat):
    if distance_rsu_01 <= 300:
        # 获取rsu信息
        array_rsu_01 = get_rsu_01_pos_and_id(rsu_id_01)

        traffic_accident_event_from_rsu(array_rsu_01[0], array_rsu_01[1], array_rsu_01[1], event_lon, event_lat)

    if distance_rsu_02 <= 300:
        array_rsu_02 = get_rsu_02_pos_and_id(rsu_id_02)

        traffic_accident_event_from_rsu(array_rsu_02[0], array_rsu_02[1], array_rsu_02[2], event_lon, event_lat)

    if distance_rsu_03 <= 300:
        array_rsu_03 = get_rsu_03_pos_and_id(rsu_id_03)
        traffic_accident_event_from_rsu(array_rsu_03[0], array_rsu_03[1], array_rsu_03[2], event_lon, event_lat)


def collision_event():
    traci.vehicle.setSpeed("2003", 10)
    traci.vehicle.setSpeed("2004", 20)
    # 关闭换道模型
    traci.vehicle.setLaneChangeMode('2003', 0b000000000000)
    traci.vehicle.setLaneChangeMode('2004', 0b000000000000)
    # 关闭跟驰模型
    traci.vehicle.setSpeedMode('2003', 00000)
    traci.vehicle.setSpeedMode('2004', 00000)

    array2003 = get_veh_info('2003')
    array2004 = get_veh_info('2004')
    lon2003 = array2003[0]
    lat2003 = array2003[1]
    lon2004 = array2004[0]
    lat2004 = array2004[1]
    speed2003 = array2003[3]
    speed2004 = array2004[3]
    relative_distance = get_distance(lat2003, lon2003, lat2004, lon2004)
    relative_speed = abs(speed2003 - speed2004)
    if relative_speed != 0.0:
        ttc = relative_distance / relative_speed
        if traci.vehicle.getLaneID('2003') == traci.vehicle.getLaneID('2004') and ttc < 3:
            # # 获取rsu信息
            array_rsu_01 = get_rsu_01_pos_and_id(rsu_id_01)
            array_rsu_02 = get_rsu_02_pos_and_id(rsu_id_02)
            array_rsu_03 = get_rsu_03_pos_and_id(rsu_id_03)
            # 碰撞事件离三个rsu的距离
            distance_rsu01 = get_distance(array_rsu_01[2], array_rsu_01[1], lat2004, lon2004)
            distance_rsu02 = get_distance(array_rsu_02[2], array_rsu_02[1], lat2004, lon2004)
            distance_rsu03 = get_distance(array_rsu_03[2], array_rsu_03[1], lat2004, lon2004)
            # 碰撞发生位置和三个rsu距离判断，在广播范围内的rsu将收集碰撞信息
            traffic_accident_distance_judge(distance_rsu01, distance_rsu02, distance_rsu03, rsu_id_01, rsu_id_02,
                                            rsu_id_03, lon2004, lat2004)
            res = r.setnx('collision', 'collision')
            if res == True:
                redis_producer('碰撞预警'.encode("utf-8"))
                r.expire('collision', 10)
            traci.vehicle.setSpeed('2004', 10.0)
            traci.vehicle.changeLane('2004', 2, 999.00)


    else:
        print('当前两车相对速度为0，无法计算TTC')
        # traci.vehicle.remove('2003', tc.REMOVE_VAPORIZED)
        # traci.vehicle.remove('2004', tc.REMOVE_VAPORIZED)


def get_event_pos_and_distance(id):
    array = get_veh_info(id)
    event_lon = array[0]
    event_lat = array[1]
    distance_rsu_01 = get_distance(event_lat, event_lon, 37.472724, 121.442927)
    distance_rsu_02 = get_distance(event_lat, event_lon, 37.461350, 121.433883)
    distance_rsu_03 = get_distance(event_lat, event_lon, 37.458871, 121.450597)

    arr = [event_lon, event_lat, distance_rsu_01, distance_rsu_02, distance_rsu_03]

    return arr


def red_light_event_from_rsu(rsu_id, rsu_lon, rsu_lat, lon_redLight, lat_redLight):
    rts_id = random.randint(0, 255)
    sign_type = '14'
    sign_lon = lon_redLight
    sign_lat = lat_redLight
    msg = '{"rsu_id":"' + rsu_id + '", "rsu_lon": "' + str(rsu_lon) + '", "rsu_lat": "' + str(rsu_lat) + \
          '", "rts_id": "' + str(rts_id) + '", "sign_type": "' + sign_type + \
          '", "sign_lon": "' + str(sign_lon) + '", "sign_lat": "' + str(sign_lat) + \
          '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
    res = r.setnx('trafficlight_rsi', 'trafficlight_rsi')
    if res == True:
        rsi_traffic_light_quene(msg)
        r.expire('trafficlight_rsi', 5)
        print(msg)


def lon_lat_offset(lon, lat, angles, dst):
    arc = 6371.393 * 1000
    lon += dst * math.sin(angles) / (arc * math.cos(lat) * 2 * math.pi / 360)
    lat += dst * math.cos(angles) / (arc * 2 * math.pi / 360)

    arr = [lon, lat]
    return arr


def barrier_event(rsu_id, rsu_lon, rsu_lat, event_lon, event_lat):
    rsu_id = rsu_id
    rsu_lon = rsu_lon
    rsu_lat = rsu_lat
    rte_id = random.randint(0, 255)
    event_type = '501'
    event_source = '0'
    msg = '{"rsu_id":"' + str(rsu_id) + '", "rsu_lon": "' + str(rsu_lon) + '", "rsu_lat": "' + str(rsu_lat) + \
          '", "rte_id": "' + str(rte_id) + '", "event_type": "' + event_type + \
          '", "event_source": "' + event_source + '", "event_lon": "' + str(event_lon) + \
          '", "event_lat": "' + str(event_lat) + '", "timestamp": "' + str(
        int(round((time.time()) * 1000))) + '"}'
    res = r.setnx('barrier_rsi', 'barrier_rsi')
    if res == True:
        rsi_barrier_quene(msg)
        r.expire('barrier_rsi', 10)
        print(msg)


def rsm_msg_quene(message):
    msg_key = 'rsm:quene'
    r.lpush(msg_key, message)


def bsm_msg_quene(message):
    msg_key = 'bsm:quene'
    r.lpush(msg_key, message)


def spat_msg_quene(message):
    msg_key = 'spat:quene'
    r.lpush(msg_key, message)


def rsi_water_quene(message):
    msg_key = 'water:quene'
    r.lpush(msg_key, message)


def rsi_xiansu_quene(message):
    msg_key = 'limit:quene'
    r.lpush(msg_key, message)


def rsi_barrier_quene(message):
    msg_key = 'build:quene'
    r.lpush(msg_key, message)


def rsi_yaxian_quene(message):
    msg_key = 'line:quene'
    r.lpush(msg_key, message)


def rsi_traffic_light_quene(message):
    msg_key = 'traffic_light:quene'
    r.lpush(msg_key, message)


def rsi_traffic_accident_quene(message):
    msg_key = 'traffic_accident:quene'
    r.lpush(msg_key, message)


def redis_producer(message):
    msg_key = 'yujing:quene'
    r.lpush(msg_key, message)


def run():
    node_id = '0'
    intersection_status_object = '5'
    list_new = set()
    event = []
    for step in range(2000870):
        traci.simulationStep(step + 1)

        # 获取路网中的车辆id
        id_list = traci.vehicle.getIDList()
        person_ids = traci.person.getIDList()
        traffic_ids = traci.trafficlight.getIDList()

        for id in list(id_list):
            list_new.add(id)
        for person in list(person_ids):
            list_new.add(person)
        for li in list_new:
            if li.startswith('10'):

                # ==================================================================================================
                # -- RSM Start(行人) -------------------------------------------------------------------------------------
                # ==================================================================================================
                array_person = get_person_info(li)

                distance_rsu_01_person = get_distance(37.472724, 121.442927, array_person[1],
                                                                        array_person[0])
                distance_rsu_02_person = get_distance(37.461350, 121.433883, array_person[1],
                                                      array_person[0])
                distance_rsu_03_person = get_distance(37.458871, 121.450597, array_person[1],
                                                      array_person[0])

                if distance_rsu_01_person <= 300:
                    rsu01_arr = get_rsu_01_pos_and_id(rsu_id_01)
                    participantType = 'B0011'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu01_arr[0] + '", "rsu_lon": "' + str(rsu01_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu01_arr[2]) + '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(array_person[0]) + '", "veh_lat": "' + str(array_person[1]) + \
                          '", "speed": "' + str(array_person[3]) + '", "heading": "' + str(array_person[2]) + '", "veh_length": "' + str(array_person[4]) + \
                          '", "veh_width": "' + str(array_person[5]) + '", "veh_height": "' + str(array_person[6]) + '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                if distance_rsu_02_person <= 300:
                    rsu02_arr = get_rsu_02_pos_and_id(rsu_id_02)
                    participantType = 'B0011'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu02_arr[0] + '", "rsu_lon": "' + str(rsu02_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu02_arr[2]) + '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(array_person[0]) + '", "veh_lat": "' + str(array_person[1]) + \
                          '", "speed": "' + str(array_person[3]) + '", "heading": "' + str(array_person[2]) + '", "veh_length": "' + str(array_person[4]) + \
                          '", "veh_width": "' + str(array_person[5]) + '", "veh_height": "' + str(array_person[6]) + '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                if distance_rsu_03_person <= 300:
                    rsu03_arr = get_rsu_03_pos_and_id(rsu_id_03)
                    participantType = 'B0011'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu03_arr[0] + '", "rsu_lon": "' + str(rsu03_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu03_arr[2]) + '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(array_person[0]) + '", "veh_lat": "' + str(array_person[1]) + \
                          '", "speed": "' + str(array_person[3]) + '", "heading": "' + str(array_person[2]) + '", "veh_length": "' + str(array_person[4]) + \
                          '", "veh_width": "' + str(array_person[5]) + '", "veh_height": "' + str(array_person[6]) + '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                # ==================================================================================================
                # -- RSM End -------------------------------------------------------------------------------------
                # ==================================================================================================
            else:
                # ==================================================================================================
                # -- RSM Start(车辆) -------------------------------------------------------------------------------------
                # ==================================================================================================

                # 获取车辆信息
                array = get_veh_info(li)
                # 获取id为2001车的经纬度
                veh_2001 = get_veh_info('2001')
                veh_2001_lon = veh_2001[0]
                veh_2001_lat = veh_2001[1]

                distance_bsm = get_distance(veh_2001_lat, veh_2001_lon, array[1], array[0])

                distance_rsu_01 = get_distance(37.472724, 121.442927, array[1], array[0])
                distance_rsu_02 = get_distance(37.461350, 121.433883, array[1], array[0])
                distance_rsu_03 = get_distance(37.458871, 121.450597, array[1], array[0])

                if distance_rsu_01 <= 300:
                    rsu01_arr = get_rsu_01_pos_and_id(rsu_id_01)
                    participantType = 'B0001'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu01_arr[0] + '", "rsu_lon": "' + str(rsu01_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu01_arr[
                              2]) + \
                          '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(
                        array[0]) + '", "veh_lat": "' + str(
                        array[1]) + \
                          '", "speed": "' + str(array[3]) + '", "heading": "' + str(
                        array[2]) + '", "veh_length": "' + str(
                        array[4]) + '", "veh_width": "' + str(array[5]) + '", "veh_height": "' + str(
                        array[6]) + '", "timestamp": "' + str(
                        int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                if distance_rsu_02 <= 300:
                    rsu02_arr = get_rsu_02_pos_and_id(rsu_id_02)
                    participantType = 'B0001'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu02_arr[0] + '", "rsu_lon": "' + str(rsu02_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu02_arr[
                              2]) + '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(
                        array[0]) + '", "veh_lat": "' + str(
                        array[1]) + '", "speed": "' + str(array[3]) + '", "heading": "' + str(
                        array[2]) + '", "veh_length": "' + \
                          str(array[4]) + '", "veh_width": "' + str(array[5]) + '", "veh_height": "' + str(
                        array[6]) + '", "timestamp": "' + str(
                        int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                if distance_rsu_03 <= 300:
                    rsu03_arr = get_rsu_03_pos_and_id(rsu_id_03)
                    participantType = 'B0001'
                    ptcId = li
                    sourceType = '2'
                    msg = '{"rsu_id":"' + rsu03_arr[0] + '", "rsu_lon": "' + str(rsu03_arr[1]) + '", "rsu_lat": "' + \
                          str(rsu03_arr[
                              2]) + '", "participantType": "' + participantType + '", "ptcId": "' + ptcId + \
                          '", "sourceType": "' + sourceType + '", "veh_lon": "' + str(
                        array[0]) + '", "veh_lat": "' + str(
                        array[1]) + '", "speed": "' + str(array[3]) + '", "heading": "' + str(
                        array[2]) + '", "veh_length": "' + \
                          str(array[4]) + '", "veh_width": "' + str(array[5]) + '", "veh_height": "' + str(
                        array[6]) + '", "timestamp": "' + str(
                        int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('rsm', 'rsm')
                    if res == True:
                        rsm_msg_quene(msg)
                        r.expire('rsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)

                    # ==================================================================================================
                    # -- RSM End -------------------------------------------------------------------------------------
                    # ==================================================================================================

                # ==================================================================================================
                # -- BSM Start -------------------------------------------------------------------------------------
                # ==================================================================================================
                if distance_bsm <= 300:
                    msg = '{"id":"' + str(id) + '", "speed": "' + str(array[3]) + \
                          '", "accel": "' + str(array[7]) + '", "lon": "' + str(array[0]) + '", "lat": "' + str(
                        array[1]) + '", "length": "' + str(array[4]) + \
                          '", "width": "' + str(array[5]) + '", "height": "' + str(
                        array[6]) + '", "angle": "' + str(
                        array[2]) + '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
                    res = r.setnx('bsm', 'bsm')
                    if res == True:
                        bsm_msg_quene(msg)
                        r.expire('bsm', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
                        print(msg)
                # ==================================================================================================
                # -- BSM End -------------------------------------------------------------------------------------
                # ==================================================================================================

        # ==================================================================================================
        # -- SPAT Start -------------------------------------------------------------------------------------
        # ==================================================================================================
        # for traffic_id in traffic_ids:
        #     phase_id = traci.trafficlight.getPhase(traffic_id) + 1
        #     state = traci.trafficlight.getRedYellowGreenState(traffic_id)
        #     end_time = ((traci.trafficlight.getNextSwitch(traffic_id)) - (traci.simulation.getTime()))
        #     link_ids = traci.trafficlight.getControlledLinks(traffic_id)
        #     lane_ids = traci.trafficlight.getControlledLanes(traffic_id)
        #     phase_duration = traci.trafficlight.getPhaseDuration(traffic_id)
        #     min_end_time = int(end_time)
        #     max_end_time = math.ceil(end_time)
        #     for link_id in link_ids:
        #         for k in link_id:
        #             link = k[0]
        #             if state.find('r') >= 0:
        #                 light_state_code = '5'
        #                 msg = '{"node_reference_id":"' + traffic_id + '", "node_id": "' + node_id + '", "intersection_status_object": "' + intersection_status_object + \
        #                       '", "phase_id": "' + str(
        #                     phase_id) + '", "light_state_code": "' + light_state_code + '", "end_time": "' + str(
        #                     end_time) + '", "link": "' + str(link) + '", "phase_duration": "' + str(phase_duration) + \
        #                       '", "min_end_time": "' + str(min_end_time) + '", "max_end_time": "' + str(
        #                     max_end_time) + '"}'
        #                 res = r.setnx('spat', 'spat')
        #                 if res == True:
        #                     spat_msg_quene(msg)
        #                     r.expire('spat', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
        #                     print(msg)
        #
        #             if state.find('y') >= 0:
        #                 light_state_code = '7'
        #                 msg = '{"node_reference_id":"' + traffic_id + '", "node_id": "' + node_id + '", "intersection_status_object": "' + intersection_status_object + \
        #                       '", "phase_id": "' + str(
        #                     phase_id) + '", "light_state_code": "' + light_state_code + '", "end_time": "' + str(
        #                     end_time) + '", "link": "' + str(link) + '", "phase_duration": "' + str(phase_duration) + \
        #                       '", "min_end_time": "' + str(min_end_time) + '", "max_end_time": "' + str(
        #                     max_end_time) + '"}'
        #                 res = r.setnx('spat', 'spat')
        #                 if res == True:
        #                     spat_msg_quene(msg)
        #                     r.expire('spat', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
        #                     print(msg)
        #
        #             if state.find('g') >= 0:
        #                 light_state_code = '3'
        #                 msg = '{"node_reference_id":"' + traffic_id + '", "node_id": "' + node_id + '", "intersection_status_object": "' + intersection_status_object + \
        #                       '", "phase_id": "' + str(
        #                     phase_id) + '", "light_state_code": "' + light_state_code + '", "end_time": "' + str(
        #                     end_time) + '", "link": "' + str(link) + '", "phase_duration": "' + str(phase_duration) + \
        #                       '", "min_end_time": "' + str(min_end_time) + '", "max_end_time": "' + str(
        #                     max_end_time) + '"}'
        #                 res = r.setnx('spat', 'spat')
        #                 if res == True:
        #                     spat_msg_quene(msg)
        #                     r.expire('spat', datetime.timedelta(0, 0, 0, 100, 0, 0, 0))
        #                     print(msg)
        # ==================================================================================================
        # -- SPAT End -------------------------------------------------------------------------------------
        # ==================================================================================================

        # 车辆碰撞
        collision_event()
        # 闯红灯预警
        tls_info = traci.vehicle.getNextTLS('2001')
        if len(tls_info) > 0:
            if tls_info[0][2] < 50 and tls_info[0][3] == 'y':
                # rsu收集闯红灯预警信息
                array = get_event_pos_and_distance('2001')
                if array[2] < 300:
                    arr = get_rsu_01_pos_and_id(rsu_id_01)
                    red_light_event_from_rsu(arr[0], arr[1], arr[2], array[0], array[1])
                if array[3] < 300:
                    arr = get_rsu_02_pos_and_id(rsu_id_02)
                    red_light_event_from_rsu(arr[0], arr[1], arr[2], array[0], array[1])
                if array[4] < 300:
                    arr = get_rsu_03_pos_and_id(rsu_id_03)
                    red_light_event_from_rsu(arr[0], arr[1], arr[2], array[0], array[1])
                # 语音提示
                res = r.setnx('go_red_light', 'go_red_light')
                if res == True:
                    redis_producer('闯红灯预警'.encode("utf-8"))
                    r.expire('go_red_light', 10)
        else:
            print(11111111)

        # 限速提醒
        xiansu_lon = 121.442687
        xiansu_lat = 37.472618
        sign_type = '39'
        rts_id = random.randint(0, 255)
        for id in id_list:
            array = get_veh_info(id)
            distance = get_distance(xiansu_lat, xiansu_lon, array[1], array[0])
            if distance < 50:
                # 语音提示
                res = r.setnx('limit', 'limit')
                if res == True:
                    redis_producer('限速提醒'.encode("utf-8"))
                    r.expire('limit', 10)
            rsu_01 = get_rsu_01_pos_and_id(rsu_id_01)
            msg = '{"rsu_id":"' + rsu_01[0] + '", "rsu_lon": "' + str(rsu_01[1]) + '", "rsu_lat": "' + str(rsu_01[2]) + \
                  '", "rts_id": "' + str(rts_id) + '", "sign_type": "' + sign_type + \
                  '", "sign_lon": "' + str(xiansu_lon) + '", "sign_lat": "' + str(xiansu_lat) + \
                  '", "timestamp": "' + str(int(round((time.time()) * 1000))) + '"}'
            res = r.setnx('xiansu_rsi', 'xiansu_rsi')
            if res == True:
                rsi_xiansu_quene(msg)
                r.expire('xiansu_rsi', 10)
                print(msg)

        # 交叉口碰撞预警
        lon_2007 = get_veh_info('2007')[0]
        lat_2007 = get_veh_info('2007')[1]
        angle_2007 = get_veh_info('2007')[2]
        arr_2007 = lon_lat_offset(lon_2007, lat_2007, angle_2007, 20.0)

        lon_2006 = get_veh_info('2006')[0]
        lat_2006 = get_veh_info('2006')[1]
        angle_2006 = get_veh_info('2006')[2]
        arr_2006 = lon_lat_offset(lon_2006, lat_2006, angle_2006, 20.0)

        distance = get_distance(arr_2007[0], arr_2007[1], arr_2006[0], arr_2006[1])
        if distance <= 20:
            # 语音提示
            res = r.setnx('intersection_collision', 'intersection_collision')
            if res == True:
                redis_producer('交叉口碰撞预警'.encode("utf-8"))
                r.expire('intersection_collision', 10)
            traci.vehicle.setSpeed('2007', 10.0)

        # 此车辆将作为障碍物在路边停着
        traci.vehicle.setStop('2009', '1036143090#0', 150.0, 1, 999.0)
        # 障碍物避让
        for id in id_list:
            signals = traci.vehicle.getSignals(id)
            speed = traci.vehicle.getSpeed(id)
            arr = get_rsu_03_pos_and_id(rsu_id_03)
            # 车辆停止并且亮着刹车灯
            if signals == 3 and speed == 0.0:
                event_lon = get_veh_info(id)[0]
                event_lat = get_veh_info(id)[1]
                event = [event_lon, event_lat]
                distance = get_distance(arr[2], arr[1], event[1], event[0])
                # rsu收集信息
                if distance <= 300:
                    barrier_event(arr[0], arr[1], arr[2], event_lon, event_lat)
            # 车辆没有停在路上
            if len(event) == 0:
                print('暂无障碍物')
            # 获取除作为障碍物的其他车辆的经纬度
            if len(event) > 0 and id != '2009':
                other_veh_lon = get_veh_info(id)[0]
                other_veh_lat = get_veh_info(id)[1]
                # 计算两点间的距离
                distance = get_distance(event[1], event[0], other_veh_lat, other_veh_lon)
                if distance <= 100:
                    # 语音提示
                    res = r.setnx('barrier', 'barrier')
                    if res == True:
                        redis_producer('前方有异常车辆，请注意绕行'.encode("utf-8"))
                        r.expire('barrier', 10)

        # 弱势者通行
        for id in id_list:
            arr = get_veh_info(id)
            if len(person_ids) > 0:
                for person in person_ids:
                    arr2 = get_person_info(person)
                    veh = lon_lat_offset(arr[0], arr[1], arr[2], 10.0)
                    ped = lon_lat_offset(arr2[0], arr2[1], arr2[2], 10.0)
                    distance = get_distance(veh[1], veh[0], ped[1], ped[0])
                    if distance < 5:
                        # 语音提示
                        res = r.setnx('pedestrian', 'pedestrian')
                        if res == True:
                            redis_producer('注意行人'.encode("utf-8"))
                            r.expire('pedestrian', 10)
                    arr_01 = get_rsu_01_pos_and_id(rsu_id_01)
                    arr_02 = get_rsu_02_pos_and_id(rsu_id_02)
                    arr_03 = get_rsu_03_pos_and_id(rsu_id_03)
                    distance_01 = get_distance(veh[1], veh[0], arr_01[2], arr_01[1])
                    distance_02 = get_distance(veh[1], veh[0], arr_02[2], arr_02[1])
                    distance_03 = get_distance(veh[1], veh[0], arr_03[2], arr_03[1])
                    traffic_accident_distance_judge(distance_01, distance_02, distance_03, rsu_id_01, rsu_id_02, rsu_id_03,
                                                    veh[0], veh[1])
            else:
                print('暂无行人')


def get_options():
    optParser = optparse.OptionParser()
    optParser.add_option("--nogui", action="store_true",
                         default=False, help="run the commandline version of sumo")
    options, args = optParser.parse_args()
    return options


sumocfgfile = "./sumo/osm.sumocfg"

# this is the main entry point of this script
if __name__ == "__main__":
    options = get_options()
    # this script has been called from the command line. It will start sumo as a
    # server, then connect and run
    if options.nogui:
        sumoBinary = checkBinary('sumo')
    else:
        sumoBinary = checkBinary('sumo-gui')

    # this is the normal way of using traci. sumo is started as a
    # subprocess and then the python script connects and runs
    traci.start([sumoBinary, "-c", sumocfgfile])
    run()
